<template>
  <div class="flex fh">
    <el-form style="width: 600px" class="pr-20" :label-width="60">
      <el-form-item label="团体">
        <el-input v-model="data.group"></el-input>
      </el-form-item>

      <el-form-item label="标题">
        <el-input v-model="data.title"></el-input>
      </el-form-item>

      <el-form-item label="内容">
        <el-input type="textarea" resize="none" :autosize="{ minRows: 6 }" v-model="data.content"></el-input>
      </el-form-item>

      <el-form-item label="">
        <el-button type="primary" @click="duplicatingShearsClick">复制图片</el-button>
      </el-form-item>
    </el-form>

    <el-card class="canvas fh">
      <el-scrollbar class="fh">
        <canvas class="fw" type="2D" ref="canvasRef"></canvas>
      </el-scrollbar>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch } from "vue";
import { ElMessage } from "element-plus";
const data = reactive({
  group: "逆水寒桃溪小鲸鱼",
  title: "",
  content: "",
});
const [year, mouth, date] = [new Date().getFullYear(), new Date().getMonth() + 1, new Date().getDate()];
const canvasRef: any = ref();

watch(
  () => data,
  () => {
    darwCanvas();
  },
  {
    deep: true,
  }
);

const darwCanvas = () => {
  const ctx = canvasRef.value.getContext("2d");
  const { offsetHeight, offsetWidth } = canvasRef.value.parentElement;
  canvasRef.value.height = offsetHeight;
  canvasRef.value.width = offsetWidth;
  ctx.clearRect(0, 0, offsetHeight, offsetWidth);

  drawHeader();
  drawBody();
  drawFooter();
  if (ctx.offsetTop > offsetHeight - 100) {
    canvasRef.value.height = ctx.offsetTop;
    ctx.clearRect(0, 0, ctx.offsetTop, offsetHeight);
    drawHeader();
    drawBody();
    drawFooter();
  }
};
/** 画抬头 */
const drawHeader = () => {
  const { offsetHeight: height, offsetWidth: width } = canvasRef.value.parentElement;
  const ctx = canvasRef.value.getContext("2d");
  //#region 背景色
  ctx.fillStyle = "#FFF";
  ctx.fillRect(0, 0, width, ctx.offsetTop || height);
  //#endregion

  //#region 标题
  ctx.fillStyle = "#ff0000";
  ctx.font = "34px bold 方正大标宋简体,FZDaBiaoSong-B06S,微软雅黑";
  ctx.textAlign = "center";
  ctx.text;
  ctx.fillText(data.group, width / 2, 97);
  //#endregion

  //#region 抬头
  ctx.font = "21px 仿宋,微软雅黑";
  ctx.textAlign = "center";
  ctx.fillText(`【政】发 ${year}-${mouth}-${date}`, width / 2, 142);
  //#endregion

  //#region 分割线
  ctx.beginPath();
  ctx.lineWidth = 1;
  ctx.strokeStyle = "red";
  ctx.moveTo(20, 168);
  ctx.lineTo(width - 20, 168);
  ctx.stroke();
  //#endregion

  ctx.offsetTop = 172;
};
/** 画内容 */
const drawBody = () => {
  const ctx = canvasRef.value.getContext("2d");
  const { offsetHeight: height, offsetWidth: width } = canvasRef.value.parentElement;
  //#region 标题
  ctx.fillStyle = "#000";
  ctx.font = "24px bold 方正小标宋简体,FZXiaoBiaoSong-B05S,黑体,微软雅黑";
  ctx.textAlign = "center";
  ctx.text;
  ctx.fillText(`关于《${data.title}》的通知`, width / 2, ctx.offsetTop + 22 + 15);
  ctx.offsetTop += 22 + 15 + 10;
  //#endregion

  ctx.font = "20px 仿宋,微软雅黑";
  ctx.textAlign = "left";
  const maxLength = Math.floor((width - 40) / 10); // 每行最多字数
  /** 分行处理 */
  const printStr = (str, offsetY) => {
    const strArr = [];
    let offset = offsetY;
    let spliceStr = "";
    let bytesCount = 0;
    const newLine = str.split("\n");
    const titleLenght = 5;
    const emptyRow = [];
    let row = 0;
    // 计算是否需要换行
    newLine.map((str) => {
      let newRow = false;
      emptyRow.push(row);
      for (let index = 0; index < str.length; index++) {
        const element = str[index];
        element.match(/[^\x00-\xff]/gi) != null ? (bytesCount += 2) : (bytesCount += 1);
        const rowMaxLength = newRow ? maxLength : maxLength - titleLenght;
        if (bytesCount < rowMaxLength && index < str.length - 1) {
          spliceStr += element;
        } else {
          spliceStr += element;
          newRow = true;
          row += 1;
          strArr.push(spliceStr);
          spliceStr = "";
          bytesCount = 0;
        }
      }
    });
    // 画canvas
    strArr.map((item, index) => {
      offset += 40;
      ctx.fillText(item, emptyRow.indexOf(index) <= -1 ? 20 : 60, offset);
    });
    return offset;
  };

  ctx.offsetTop = printStr(data.content, ctx.offsetTop);
};
/** 画页脚 */
const drawFooter = () => {
  const { offsetHeight: height, offsetWidth: width } = canvasRef.value.parentElement;
  const ctx = canvasRef.value.getContext("2d");
  ctx.font = "20px 仿宋,微软雅黑";
  ctx.textAlign = "right";
  let offset = ctx.offsetTop + 80;
  ctx.fillText(`${data.group}单位`, width - 20, offset);
  offset += 30;
  ctx.fillText(`${year}年${mouth}月${date}日`, width - 20, offset);

  //#region 分割线
  ctx.beginPath();
  ctx.lineWidth = 1;
  ctx.strokeStyle = "red";
  ctx.moveTo(20, offset + 65);
  ctx.lineTo(width - 20, offset + 65);
  ctx.stroke();
  //#endregion

  // 绘制印章边框
  ctx.lineWidth = 4;
  ctx.strokeStyle = "#ff0000";
  ctx.beginPath();
  ctx.arc(width - 90, offset - 30, 70, 0, Math.PI * 2);
  ctx.stroke();

  //画五角星
  create5star(ctx, width - 90, offset - 30, 15, "#ff0000", 0);

  // 绘制印章名称
  ctx.font = "12px Helvetica";
  ctx.textBaseline = "middle"; //设置文本的垂直对齐方式
  ctx.textAlign = "center"; //设置文本的水平对对齐方式
  ctx.lineWidth = 1;
  ctx.fillStyle = "#de000b";
  ctx.fillText("专用章", width - 90, offset + 5);

  // 绘制印章单位
  ctx.translate(width - 90, offset - 30); // 平移到此位置,
  ctx.font = "15px bold Helvetica";
  const count = data.group.length; // 字数
  const angle = (4 * Math.PI) / (3 * (count - 1)); // 字间角度
  const chars = data.group.split("");
  for (var i = 0; i < count; i++) {
    let c = chars[i]; // 需要绘制的字符
    if (i == 0) ctx.rotate((5 * Math.PI) / 6);
    else ctx.rotate(angle);
    ctx.save();
    ctx.translate(60, 0); // 平移到此位置,此时字和x轴垂直
    ctx.rotate(Math.PI / 2); // 旋转90度,让字平行于x轴
    ctx.fillText(c, 0, 5); // 此点为字的中心点
    ctx.restore();
  }

  ctx.offsetTop += 280;
};
/** 画电子印章的星星 */
const create5star = (context, sx, sy, radius, color, rotato) => {
  context.save();
  context.fillStyle = color;
  context.translate(sx, sy); //移动坐标原点
  context.rotate(Math.PI + rotato); //旋转
  context.beginPath(); //创建路径
  var x = Math.sin(0);
  var y = Math.cos(0);
  var dig = (Math.PI / 5) * 4;
  for (var i = 0; i < 5; i++) {
    //画五角星的五条边
    var x = Math.sin(i * dig);
    var y = Math.cos(i * dig);
    context.lineTo(x * radius, y * radius);
  }
  context.closePath();
  context.stroke();
  context.fill();
  context.restore();
};
/** 导出图片并复制到剪切板 */
const duplicatingShearsClick = async () => {
  let dataURL = canvasRef.value.toDataURL({ pixelRatio: 1 });
  const data = await fetch(dataURL);
  const blob = await data.blob();
  let ClipboardItem = window.ClipboardItem;
  await navigator.clipboard.write([
    new ClipboardItem({
      [blob.type]: blob,
    }),
  ]);
  ElMessage.success("复制成功~~");
};

onMounted(() => {
  darwCanvas();
});
</script>

<style scoped lang="scss">
::v-deep {
  .el-card__body {
    padding: 0;
    height: 100%;
  }
}

.flex {
  display: flex;
}

.canvas {
  width: 700px;
}
</style>
